package com.gylang.core.util;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.core.annotation.Order;

import java.util.Comparator;

/**
 * @author gylang
 * data 2021/1/8
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class OrderUtils {

    public static final int NULL_ORDER_VALUE_IS_MAX = Integer.MAX_VALUE;
    public static final int NULL_ORDER_VALUE_IS_MIN = Integer.MIN_VALUE;

    /**
     * order 注解排序比较
     *
     * @param o1             01
     * @param o2             02
     * @param nullOrderValue 当排序对象为null 时的默认值
     * @return 排序值
     */
    public static int sort(Order o1, Order o2, int nullOrderValue) {

        int o1v = null == o1 ? nullOrderValue : o1.value();
        int o2v = null == o2 ? nullOrderValue : o2.value();

        return Integer.compare(o1v, o2v);
    }

    /**
     * order 类获取注解排序比较
     *
     * @param clazz1 排序类
     * @param clazz2 排序类
     * @return 排序值
     */
    public static int sort(Class<?> clazz1, Class<?> clazz2) {

        return sort(clazz1.getAnnotation(Order.class), clazz2.getAnnotation(Order.class), NULL_ORDER_VALUE_IS_MAX);
    }

    /**
     * order 注解排序比较
     *
     * @param clazz1         排序类
     * @param clazz2         排序类
     * @param nullOrderValue 当排序对象为null 时的默认值
     * @return 排序值
     */
    public static int sort(Class<?> clazz1, Class<?> clazz2, int nullOrderValue) {
        Order o1v = null == clazz1 ? null : clazz1.getAnnotation(Order.class);
        Order o2v = null == clazz2 ? null : clazz2.getAnnotation(Order.class);
        return sort(o1v, o2v, nullOrderValue);
    }

    /**
     * order 类获取注解排序比较
     *
     * @param obj1 排序类
     * @param obj2 排序类
     * @return 排序值
     */
    public static int sort(Object obj1, Object obj2) {

        return sort(obj1, obj2, NULL_ORDER_VALUE_IS_MAX);
    }

    /**
     * order 注解排序比较
     *
     * @param obj1           排序类
     * @param obj2           排序类
     * @param nullOrderValue 当排序对象为null 时的默认值
     * @return 排序值
     */
    public static int sort(Object obj1, Object obj2, int nullOrderValue) {
        Class<?> c1v = null == obj1 ? null : obj1.getClass();
        Class<?> c2v = null == obj2 ? null : obj2.getClass();
        return sort(c1v, c2v, nullOrderValue);
    }

    @NoArgsConstructor
    @AllArgsConstructor
    public static class OrderSort implements Comparator<Order> {
        private int nullValue = NULL_ORDER_VALUE_IS_MAX;

        @Override
        public int compare(Order o1, Order o2) {
            return sort(o1, o2, nullValue);
        }
    }

    @NoArgsConstructor
    @AllArgsConstructor
    public static class ClassOrder implements Comparator<Class<?>> {

        private int nullValue = NULL_ORDER_VALUE_IS_MAX;

        @Override
        public int compare(Class<?> o1, Class<?> o2) {
            return sort(o1, o2, nullValue);
        }
    }

    @NoArgsConstructor
    @AllArgsConstructor
    public static class ObjectOrder implements Comparator<Object> {

        private int nullValue = NULL_ORDER_VALUE_IS_MAX;

        @Override
        public int compare(Object o1, Object o2) {
            return sort(o1, o2, nullValue);
        }
    }
}
